package cn.yeziji.netty.adapter;

import cn.yeziji.forum.basic.netty.guetbook.GuestbookMessage;
import cn.yeziji.forum.common.key.GuestbookCacheKey;
import cn.yeziji.forum.utils.ListsCollect;
import cn.yeziji.forum.utils.RedisUtils;
import cn.yeziji.netty.config.handler.NettyWebsocketHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * 打卡簿适配器
 *
 * @author gzkemays
 * @since 2022/11/10 6:11 PM
 */
@Slf4j
public class GuestbookAdapter extends SelectedTypes<GuestbookMessage>
    implements CommunicationAdapters {
  NettyWebsocketHandler nettyWebsocketHandler = getNettyWebsocketHandler();
  RedisUtils redisUtils = new RedisUtils(getRedisTemplate());

  public GuestbookAdapter(Integer type, String text) {
    super(type, text, GuestbookMessage.class);
  }

  @Override
  public void notice(ChannelHandlerContext channelHandlerContext) {
    if (text == null) {
      List<ChannelHandlerContext> guestbookList = nettyWebsocketHandler.getGuestbookList();
      // 进入、退出都是通过连接判断，如果连接存在则退出，不存在则进入
      if (guestbookList.contains(channelHandlerContext)) {
        log.info("有用户退出打卡圣地");
        guestbookList.remove(channelHandlerContext);
      } else {
        log.info("有用户进入打卡圣地");
        guestbookList.add(channelHandlerContext);
        List<GuestbookMessage> list = new ArrayList<>();
        list.addAll(
            ListsCollect.castList(
                redisUtils.list0Range(GuestbookCacheKey.USER_KEY), GuestbookMessage.class));
        list.addAll(
            ListsCollect.castList(
                redisUtils.list0Range(GuestbookCacheKey.GUEST_KEY), GuestbookMessage.class));
        writeAndFlush(channelHandlerContext, list);
      }
    }
  }

  @Override
  public Object dispose(ChannelHandlerContext channelHandlerContext) {
    List<ChannelHandlerContext> guestbookList = nettyWebsocketHandler.getGuestbookList();
    // 保存至缓存
    if (data.getNickname() != null) redisUtils.listFooterPushAll(GuestbookCacheKey.USER_KEY, data);
    else redisUtils.listFooterPushAll(GuestbookCacheKey.GUEST_KEY, data);
    // 发送消息给其他客户端
    guestbookList.forEach(
        ctx -> {
          if (!ctx.equals(channelHandlerContext)) writeAndFlush(ctx, data);
        });
    return data;
  }
}
